package service

import (
	"crypto/x509"
	"encoding/pem"
	"lktx-dns/bean"
	"lktx-dns/config"
	"lktx-dns/db"
	"lktx-dns/entity"
	"log"
	"strconv"
	"time"
)

type ProxyService struct {
}

func (receiver ProxyService) InitProxy() {
	var results []*entity.ProxyInfoEntity
	db.DB.Model(&entity.ProxyInfoEntity{}).Where("status = 1 ").Find(&results)
	config.Proxys.Range(func(key, value any) bool {
		config.Proxys.Delete(key)
		return true
	})
	for _, result := range results {
		value, ok := config.Proxys.Load(*result.Domain)
		if ok {
			entities := value.([]*entity.ProxyInfoEntity)
			entities = append(entities, result)
			config.Proxys.Store(*result.Domain, entities)
		} else {
			var infos []*entity.ProxyInfoEntity
			infos = append(infos, result)
			config.Proxys.Store(*result.Domain, infos)
		}
	}
}

func (receiver *ProxyService) ProxyList(page int, pageSize int) *bean.ResPage {
	receiver.InitProxy()
	var results []*entity.ProxyInfoEntity
	var total int64
	db.DB.Model(&entity.ProxyInfoEntity{}).Order("id desc").Count(&total).Offset((page - 1) * pageSize).Limit(pageSize).Find(&results)
	// 计算总记录数并执行分页查询

	for _, data := range results {
		if data.CertificateContent != nil && len(*data.CertificateContent) > 0 {
			// 解码 PEM 数据
			block, _ := pem.Decode([]byte(*data.CertificateContent))
			if block == nil {
				data.Tips = "证书格式错误.."
				continue
			}
			// 解析证书
			cert, err := x509.ParseCertificate(block.Bytes)
			if err != nil {
				log.Printf(err.Error())
				data.Tips = "证书格式错误."
				continue
			} else {
				// 获取当前时间
				now := time.Now()
				// 检查证书是否过期
				if now.After(cert.NotAfter) {
					data.Tips = "证书已经过期"
				} else {
					duration := cert.NotAfter.Sub(now)
					daysRemaining := int(duration.Hours() / 24)
					data.Tips = "证书还有" + strconv.Itoa(daysRemaining) + "天过期"
				}
			}
		} else {
			data.Tips = "无证书"
		}
	}

	return bean.PageOk(total, results)
}

func (receiver *ProxyService) ProxyListByKey(keyword string) *bean.ResData {
	var results []entity.ProxyInfoEntity
	tx := db.DB.Model(&entity.ProxyInfoEntity{})
	if len(keyword) > 0 {
		tx.Where("domain like ?", "%"+keyword+"%")
	}
	tx.Order("id desc").Find(&results)
	return bean.ResOk(results)
}

func (receiver *ProxyService) ProxyRemoveData(id int) bool {
	userQuery := &entity.ProxyInfoEntity{}
	db.DB.Where("id = ? ", id).First(userQuery)
	if userQuery != nil {
		var results entity.ProxyInfoEntity
		db.DB.Where("id = ?", id).Delete(&results)
		receiver.InitProxy()
		return true
	}
	return false
}

func (receiver *ProxyService) ProxySaveData(userDomain entity.ProxyInfoEntity) error {
	ca := CaService{}
	if userDomain.OpenSsl == "1" {
		key, cert, err2 := ca.GenSSL(*userDomain.Domain)
		if err2 == nil {
			userDomain.CertificateKey = &key
			userDomain.CertificateContent = &cert
		}
	} else {
		userDomain.CertificateKey = nil
		userDomain.CertificateContent = nil
	}
	if userDomain.Id == nil {
		db.DB.Save(&userDomain)
	} else {
		db.DB.Model(&entity.ProxyInfoEntity{}).Where("id = ?", userDomain.Id).Update("open_ssl", userDomain.OpenSsl).Update("certificate_key", userDomain.CertificateKey).Update("certificate_content", userDomain.CertificateContent).Update("ip", userDomain.IP).Update("status", userDomain.Status).Update("port", userDomain.Port).Update("domain", userDomain.Domain).Update("open_ip", userDomain.OpenIp).Update("open_cors", userDomain.OpenCors).Update("desc", userDomain.Desc)
	}
	receiver.InitProxy()
	return nil
}

func (receiver *ProxyService) ProxyStatus(id int, status string) error {
	db.DB.Model(&entity.ProxyInfoEntity{}).Where("id = ?", id).Update("status", status)
	receiver.InitProxy()
	return nil
}
